﻿using ExamCommon;
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using ExamUtils;
using System.Threading;

namespace ExamClientBLL
{
    public static class ClientSocketService
    {
        /// <summary>
        /// 声明负责通信的客户端socket
        /// </summary>
        private static Socket clientTCPSocket = null;

        /// <summary>
        /// 创建客户端socket服务
        /// </summary>
        /// <returns></returns>
        public static bool CreateClientTCPSocket(string ip, int port)
        {
            // 判断ip和端口是否合法
            if (string.IsNullOrEmpty(ip) || port <= 0 && 65535 <= port)
            {
                return false;
            }
            // 已经存在一个正常的socket连接
            if (clientTCPSocket != null && clientTCPSocket.Connected)
            {
                string[] ipAndPort = clientTCPSocket.RemoteEndPoint.ToString().Split(':');
                // 判断申请创建的连接ip和端口是否是和已连接的ip和端口一致, 如果一致则不用再重新创建
                if (ip.Equals(ipAndPort[0]) && port.Equals(Convert.ToInt32(ipAndPort[1])))
                {
                    return true;
                }
            }

            try
            {
                // 初始化客户端socket
                clientTCPSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                // 解析IP地址
                IPAddress ipAddress = IPAddress.Parse(ip);
                // 构建endPoint
                IPEndPoint iPEndPoint = new IPEndPoint(ipAddress, port);
                Console.WriteLine("尝试与服务器建立连接...");
                // 连接服务器
                clientTCPSocket.Connect(iPEndPoint);
            }
            catch (Exception ex)
            {
                Console.WriteLine("连接服务器失败! 异常: " + ex.Message);
                return false;
            }

            // 开启一个线程用于持续接收服务器消息, 线程池
            ThreadPool.QueueUserWorkItem(ReceiveServerMsg, clientTCPSocket);

            return true;
        }

        /// <summary>
        /// 接收来自服务器的消息
        /// </summary>
        /// <param name="socket"></param>
        private static void ReceiveServerMsg(object socket)
        {
            if (socket == null)
            {
                return;
            }
            // object转换为Socket
            Socket connectedSocket = socket as Socket;
            Console.WriteLine("与服务器: " + connectedSocket.RemoteEndPoint.ToString() + "连接成功!");

            while (true)
            {
                // 接收消息, 只负责收消息
                Message message = SocketHelper.ReceiveMessage(connectedSocket);
                // 如果消息为null,则说明服务端被关闭
                if (message == null)
                {
                    break;
                }
                // 将消息交给消息处理类
                MessageHandler handling = new MessageHandler();
                handling.HandleMessage(message);
            }
        }

        /// <summary>
        /// 客户端给服务器发送消息
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public static bool SendMessage(Message msg)
        {
            ThreadPool.QueueUserWorkItem(SendMsg, msg);
            return true;
        }

        /// <summary>
        /// 封装发消息方法, 方便线程池调用 //////////////////需要修改
        /// </summary>
        /// <param name="msg"></param>
        private static void SendMsg(object msg)
        {
            Message message = msg as Message;
            SocketHelper.SendMessage(clientTCPSocket, message);
        }

        /// <summary>
        /// 关闭socket连接
        /// </summary>
        public static void CloseClientTCPSocket()
        {
            if (clientTCPSocket != null)
            {
                clientTCPSocket.Shutdown(SocketShutdown.Both);
                clientTCPSocket.Close();
            }
        }

    }
}
